package org.qy.hbase.server.utils;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.hbase.client.Mutation;
import org.apache.hadoop.hbase.client.Put;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 写入数据辅助工具类
 * @author HeQixuan
 */
public class MutationUtils{

    private static Logger logger = LoggerFactory.getLogger(MutationUtils.class);

    private static final String ID = "ID";

    /**
     * 产生Hbase插入数据对象
     * @param dataList
     * @param <T>
     * @return
     */
    public static <T> List<Mutation> generate(List<T> dataList){
        List<Mutation> resultList = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(dataList)){
            dataList.forEach(t -> {
                final Put put = generate(t);
                if(!Objects.isNull(put)){
                    resultList.add(put);
                }
            });
        }
        return resultList;
    }

    /**
     * 产生插入Hbase数据对象
     * @param t
     * @param <T>
     * @return
     */
    public static <T> Put generate(T t){
        if(Objects.isNull(t)){
            return null;
        }
        JSONObject columns = new JSONObject();
        try {
            generateColumn(t, t.getClass(), columns);
            final String id = columns.getString(ID);
            if(StringUtils.isBlank(id)){
                logger.error("ID属性不能为空!");
                return null;
            }
            Put p = new Put(id.getBytes());
            //ID不作为列族中的属性进行写入
            columns.remove(ID);
            columns.forEach((key, value) -> {
                p.addColumn(RowMapperUtils.DEFAULT_FAMILY.getBytes(), key.getBytes(), value.toString().getBytes());
            });
            return p;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return null;
    }

    private static <T>  void generateColumn(T t, Class cls, JSONObject columns){
        final Class superclass = cls.getSuperclass();
        if(superclass != null){
            generateColumn(t, superclass, columns);
        }
        final Field[] declaredFields = cls.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            final String name = declaredField.getName();
            if("serialVersionUID".equals(declaredField.getName())){
                continue;
            }
            try {
                String columnName = ColumnUtils.camelToUnderline(name);
                //若该属性值存在且有值则将其赋值给实例对象
                String sName = "get" + StringUtils.capitalize(name);
                Method declaredMethod = cls.getDeclaredMethod(sName, null);
                //此处所有的建表都为String类型
                final Object value = declaredMethod.invoke(t, null);
                if(!Objects.isNull(value)){
                    columns.put(columnName, value);
                }
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
            }
        }
    }

}
